﻿using Microsoft.EntityFrameworkCore;
using tms.Admins;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.BackgroundJobs.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.TenantManagement;
using Volo.Abp.TenantManagement.EntityFrameworkCore;

namespace tms.EntityFrameworkCore
{
    [ReplaceDbContext(typeof(ITenantManagementDbContext))]
    [ConnectionStringName("Default")]
    public class tmsDbContext : 
        AbpDbContext<tmsDbContext>,
        ITenantManagementDbContext
    {
        /* Add DbSet properties for your Aggregate Roots / Entities here. */
        
        #region Entities from the modules
        
        /* Notice: We only implemented IIdentityDbContext and ITenantManagementDbContext
         * and replaced them for this DbContext. This allows you to perform JOIN
         * queries for the entities of these modules over the repositories easily. You
         * typically don't need that for other modules. But, if you need, you can
         * implement the DbContext interface of the needed module and use ReplaceDbContext
         * attribute just like IIdentityDbContext and ITenantManagementDbContext.
         *
         * More info: Replacing a DbContext of a module ensures that the related module
         * uses this DbContext on runtime. Otherwise, it will use its own DbContext class.
         */
        
        //Identity        
        
        // Tenant Management
        public DbSet<Tenant> Tenants { get; set; }
        public DbSet<TenantConnectionString> TenantConnectionStrings { get; set; }

        #endregion

        public DbSet<Admin> Admin { get; set; }
        public DbSet<Admin_Role> Admin_Role { get; set; }
        public DbSet<ApprovalDetail> ApprovalDetail { get; set; }
        public DbSet<Department> Department { get; set; }
        public DbSet<Dic> Dic { get; set; }
        public DbSet<DicType> DicType { get; set; }
        public DbSet<Employee> Employee { get; set; }
        public DbSet<EntryApproval> EntryApproval { get; set; }
        public DbSet<Flow> Flow { get; set; }
        public DbSet<FlowNode> FlowNode { get; set; }
        public DbSet<FlowState> FlowState { get; set; }
        public DbSet<Jobtitle> Jobtitle { get; set; }
        public DbSet<Menu> Menu { get; set; }
        public DbSet<Menu_Role> Menu_Role { get; set; }
        public DbSet<Role> Role { get; set; }

        public tmsDbContext(DbContextOptions<tmsDbContext> options)
            : base(options)
        {

        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            /* Include modules to your migration db context */

            builder.ConfigureSettingManagement();
            builder.ConfigureBackgroundJobs();
            builder.ConfigureAuditLogging();
            builder.ConfigureTenantManagement();

            builder.Entity<Admin>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(Admin), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(m => m.UserName).HasMaxLength(50).IsRequired();
                b.Property(m => m.Password).HasMaxLength(50).IsRequired();
                b.Property(m => m.LastLoginIP).HasMaxLength(50);
                b.HasOne<Employee>().WithMany().HasForeignKey(m => m.EmployeeId);
            });


            builder.Entity<Admin_Role>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(Admin_Role), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.HasOne<Admin>().WithMany().HasForeignKey(m => m.AdminId);
                b.HasOne<Role>().WithMany().HasForeignKey(m => m.RoleId);
            });


            builder.Entity<ApprovalDetail>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(ApprovalDetail), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(m => m.ApprovaState).HasMaxLength(50).IsRequired();
                b.Property(m => m.RejectReason).HasMaxLength(500).IsRequired();
            });


            builder.Entity<Department>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(Department), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(m => m.DepartmentName).HasMaxLength(50).IsRequired();
            });


            builder.Entity<Dic>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(Dic), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(m => m.DicName).HasMaxLength(50).IsRequired();
                b.HasOne<DicType>().WithMany().HasForeignKey(m => m.TypeId);
            });


            builder.Entity<DicType>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(DicType), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(m => m.TypeCode).HasMaxLength(50).IsRequired();
                b.Property(m => m.TypeName).HasMaxLength(50).IsRequired();
            });


            builder.Entity<Employee>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(Employee), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(m => m.EmployeeName).HasMaxLength(50).IsRequired();
                b.Property(m => m.Sex).HasMaxLength(50).IsRequired();
                b.Property(m => m.Phone).HasMaxLength(50);
                b.Property(m => m.School).HasMaxLength(50);
                b.Property(m => m.Domain).HasMaxLength(50).IsRequired();
                b.Property(m => m.Address).HasMaxLength(50);
                b.Property(m => m.Edu).HasMaxLength(50).IsRequired();
                b.Property(m => m.Politics).HasMaxLength(50);
                b.Property(m => m.Nation).HasMaxLength(50);
                b.Property(m => m.Marriage).HasMaxLength(50).IsRequired();
                b.Property(m => m.Email).HasMaxLength(50).IsRequired();
                b.Property(m => m.Idcard).HasMaxLength(50).IsRequired();
                b.Property(m => m.Status).HasMaxLength(50);
                b.Property(m => m.EmployeeType).HasMaxLength(50);
                b.HasOne<Department>().WithMany().HasForeignKey(m => m.DepartmentId);
                b.HasOne<Jobtitle>().WithMany().HasForeignKey(m => m.JobtitleId);
            });


            builder.Entity<EntryApproval>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(EntryApproval), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(m => m.EmployeeName).HasMaxLength(50).IsRequired();
                b.Property(m => m.HigherUp).HasMaxLength(50).IsRequired();
                b.Property(m => m.Remark);
                b.Property(m => m.ApprovalStatus).HasMaxLength(50);
                b.HasOne<Employee>().WithMany().HasForeignKey(m => m.EmployeeId);
            });


            builder.Entity<Flow>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(Flow), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(m => m.FlowName).HasMaxLength(50).IsRequired();
                b.Property(m => m.FlowCode).HasMaxLength(50).IsRequired();
                b.Property(m => m.FlowData).IsRequired();
                b.HasOne<Menu>().WithMany().HasForeignKey(m => m.MenuId);
            });


            builder.Entity<FlowNode>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(FlowNode), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(m => m.NodeCode).HasMaxLength(50).IsRequired();
                b.HasOne<Employee>().WithMany().HasForeignKey(m => m.EmployeeId);
                b.HasOne<Flow>().WithMany().HasForeignKey(m => m.FlowId);
                b.HasOne<FlowState>().WithMany().HasForeignKey(m => m.StateId);
            });


            builder.Entity<FlowState>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(FlowState), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(m => m.StateName).HasMaxLength(50);
                b.Property(m => m.StateDescription).HasMaxLength(500);
            });


            builder.Entity<Jobtitle>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(Jobtitle), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(m => m.JobtitleName).HasMaxLength(50).IsRequired();
                b.Property(m => m.Alias).HasMaxLength(50).IsRequired();
            });


            builder.Entity<Menu>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(Menu), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(m => m.MenuName).HasMaxLength(50).IsRequired();
                b.Property(m => m.MenuRoute).HasMaxLength(50);
                b.Property(m => m.ComponentPath).HasMaxLength(50);
                b.Property(m => m.Permission).HasMaxLength(50);
            });


            builder.Entity<Menu_Role>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(Menu_Role), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.HasOne<Menu>().WithMany().HasForeignKey(m => m.MenuId);
                b.HasOne<Role>().WithMany().HasForeignKey(m => m.RoleId);
            });


            builder.Entity<Role>(b =>
            {
                b.ToTable(tmsConsts.DbTablePrefix + nameof(Role), tmsConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(m => m.RoleName).HasMaxLength(50).IsRequired();
                b.Property(m => m.RoleCode).HasMaxLength(50).IsRequired();
                b.Property(m => m.Common);
            });
        }
    }
}
